package com.atguigu.controller;

import com.atguigu.client.OrderFeignClient;
import com.atguigu.client.UserFeignClient;
import com.atguigu.constant.MqConst;
import com.atguigu.constant.RedisConst;
import com.atguigu.entity.*;
import com.atguigu.result.RetVal;
import com.atguigu.result.RetValCodeEnum;
import com.atguigu.service.SeckillProductService;
import com.atguigu.util.AuthContextHolder;
import com.atguigu.util.MD5;
import com.atguigu.utils.DateUtil;
import com.baomidou.mybatisplus.extension.api.R;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@RestController
@RequestMapping("/seckill")
public class SeckillController {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    SeckillProductService seckillProductService;
    @Autowired
    RabbitTemplate rabbitTemplate;
    @Autowired
    UserFeignClient userFeignClient;
    @Autowired
    OrderFeignClient orderFeignClient;

    //1.查询所有的秒杀商品列表
    @GetMapping("queryAllSeckillProduct")
    public RetVal queryAllSeckillProduct(){
        List<SeckillProduct> se = redisTemplate.boundHashOps(RedisConst.SECKILL_PRODUCT).values();
        return RetVal.ok(se);
    }

    //2.秒杀商品详情页面编写
    @GetMapping("getSecKillProductBySkuId/{skuId}")
    public RetVal getSecKillProductBySkuId(@PathVariable Long skuId){
        SeckillProduct s=seckillProductService.getSeckillProductFromRedis(skuId);
        return RetVal.ok(s);
    }
    //3.生成抢购码 防止用户直接跳过商品详情进入秒杀地址
    @GetMapping("generateSeckillCode/{skuId}")
    public RetVal generateSeckillCode(@PathVariable Long skuId, HttpServletRequest request){
        String userId = AuthContextHolder.getUserId(request);
        if (!StringUtils.isEmpty(userId)){
            SeckillProduct seckillProduct = seckillProductService.getSeckillProductFromRedis(skuId);
            Date currentTime = new Date();
            if (DateUtil.dateCompare(seckillProduct.getStartTime(),currentTime)&&
            DateUtil.dateCompare(currentTime, seckillProduct.getEndTime())){
                String seckillCode = MD5.encrypt(userId);
                return RetVal.ok(seckillCode);
            }
        }
        return RetVal.fail().message("请先登陆再抢购");
    }

    //商品的预下单
    @PostMapping("prepareSeckill/{skuId}")
    public RetVal seckillSeckill(@PathVariable Long skuId,String seckillCode,HttpServletRequest request){
        String userId = AuthContextHolder.getUserId(request);
        if (!MD5.encrypt(userId).equals(seckillCode)){
            //用户不匹配返回异常
            return RetVal.build(null, RetValCodeEnum.SECKILL_ILLEGAL);
        }
        //该商品是否可秒杀,状态码
        String state=(String)redisTemplate.opsForValue().get(RedisConst.SECKILL_STATE_PREFIX+skuId);
        if (StringUtils.isEmpty(state)){
             return RetVal.build(null, RetValCodeEnum.SECKILL_ILLEGAL);
        }
        if (RedisConst.CAN_SECKILL.equals(state)){
            UserSeckillSkuInfo userSeckillSkuInfo = new UserSeckillSkuInfo();
            userSeckillSkuInfo.setUserId(userId);
            userSeckillSkuInfo.setSkuId(skuId);
            rabbitTemplate.convertAndSend(MqConst.PREPARE_SECKILL_EXCHANGE,MqConst.PREPARE_SECKILL_ROUTE_KEY,userSeckillSkuInfo);
        }else {
            //秒杀已买完
            return RetVal.build(null, RetValCodeEnum.SECKILL_FINISH);
        }
        return RetVal.ok();
    }

    //5.判断用户是否有抢购资格
    @GetMapping("hasQualified/{skuId}")
    public RetVal hasQualified(@PathVariable Long skuId, HttpServletRequest request){
        String userId = AuthContextHolder.getUserId(request);
        return seckillProductService.hasQualified(skuId,userId);
    }
    //秒杀确认订单信息
    @GetMapping("seckillConfirm")
    public RetVal seckillConfirm(HttpServletRequest request){
        String userId = AuthContextHolder.getUserId(request);
        //秒杀到的预售商品订单信息
        PrepareSeckillOrder prepareSeckillOrder = (PrepareSeckillOrder)redisTemplate.boundHashOps(RedisConst.PREPARE_SECKILL_USERID_ORDER).get(userId);
        if (prepareSeckillOrder==null){
            return RetVal.fail().message("请求非法");
        }
        //获取用户的收货地址
        List<UserAddress> userAddressList = userFeignClient.getAddressByUserId(userId);
        //用户秒杀到的商品
        SeckillProduct seckillProduct = prepareSeckillOrder.getSeckillProduct();
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setSkuId(seckillProduct.getSkuId());
        orderDetail.setSkuName(seckillProduct.getSkuName());
        orderDetail.setImgUrl(seckillProduct.getSkuDefaultImg());
        orderDetail.setSkuNum(prepareSeckillOrder.getBuyNum()+"");
        orderDetail.setOrderPrice(seckillProduct.getCostPrice());
        List<OrderDetail> orderDetailList = new ArrayList<>();
        orderDetailList.add(orderDetail);
        //返回数据给页面
        Map<String, Object> map = new HashMap<>();
        map.put("userAddressList", userAddressList);
        map.put("orderDetailList",orderDetailList);
        map.put("totalMoney",seckillProduct.getCostPrice());
        return RetVal.ok(map);
    }
//提交秒杀订单信息
    @GetMapping("submitSecKillOrder")
    public RetVal submitSecKillOrder(HttpServletRequest request,@RequestBody OrderInfo orderInfo){
        String userId = AuthContextHolder.getUserId(request);
        //判断用户是否有预下单
        PrepareSeckillOrder prepareSeckillOrder =(PrepareSeckillOrder) redisTemplate.boundHashOps(RedisConst.PREPARE_SECKILL_USERID_ORDER).get(userId);
        if (prepareSeckillOrder==null){
            return RetVal.fail().message("非法操作");
        }
        //远程调用shop-order微服务
        Long orderId = orderFeignClient.saveOrderInfo(orderInfo);
        if (orderId==null){
            return RetVal.fail().message("下单失败");
        }
        //根基用户user删除预订单
        redisTemplate.boundHashOps(RedisConst.PREPARE_SECKILL_USERID_ORDER).delete(userId);
        //把用户购买的商品信息保存到缓存当中,用于判断用户是否购买过商品
        redisTemplate.boundHashOps(RedisConst.BOUGHT_SECKILL_USER_ORDER).put(userId, prepareSeckillOrder);
        return RetVal.ok(orderId);
    }
}












